﻿using System;
using System.Collections.Generic;
using BuzzwordBingo.Interface;
using NUnit.Framework;

namespace BuzzwordBingo.Entities.Test
{
    /// <summary>
    /// Summary description for EntitiesTest
    /// </summary>
    [TestFixture]
    public class BingoEventFixture
    {

        private bool _eventReceived = false;
        private IParticipant _winner = null;

        [Test]
        public void AddDates()
        {
            IBingoEvent myEvent = new BingoEvent();
            DateTime start = DateTime.Parse("2007-01-01 14:00");
            DateTime end = DateTime.Parse("2007-01-01 16:00");
            myEvent.AddEventDates(start, end);

            Assert.AreEqual(start, myEvent.StartDate);
            Assert.AreEqual(end, myEvent.EndDate);
        }

        [Test, ExpectedException(typeof(EntitiesException), ExpectedMessage = "'start date' not less than 'end date'")]
        public void AddDatesWithException()
        {
            IBingoEvent myEvent = new BingoEvent();
            DateTime start = DateTime.Parse("2007-01-01 14:00");
            myEvent.AddEventDates(start, start);
        }

        [Test]
        public void AddSpeaker()
        {
            IBingoEvent myEvent = new BingoEvent();
            string speaker = "Mr. Foobar";
            myEvent.Speaker = speaker;

            Assert.AreEqual(speaker, myEvent.Speaker);
        }

        [Test]
        public void AddOrganiser()
        {
            IBingoEvent myEvent = new BingoEvent();
            string organiser = "Joe";
            myEvent.Organiser = organiser;

            Assert.AreEqual(organiser, myEvent.Organiser);
        }

        [Test]
        public void AddParticipant()
        {
            string email = "email@dot.com";
            IParticipant myParticipant = new Participant(email);
            IBingoEvent myEvent = new BingoEvent();
            myEvent.AddParticipant(myParticipant);

            Assert.AreEqual(myParticipant, myEvent.ParticipantList[0]);
        }

        [Test]
        public void AddBuzzWord()
        {
            string fuzz = "foobar";
            IBuzzWord myBuzzWord = new BuzzWord(fuzz);
            IBingoEvent myEvent = new BingoEvent();
            myEvent.AddBuzzWord(myBuzzWord);

            Assert.AreEqual(myBuzzWord, myEvent.Category.BuzzWordList[0]);
        }

        [Test]
        public void GetUniqueRandomNumber()
        {
            BingoEvent myEvent = new BingoEvent();

            for (int i = 0; i < 5; i++)
                myEvent.AddBuzzWord(new BuzzWord(i.ToString()));

            List<int> numberList = new List<int>();
            int number;
            for (int i = 0; i < 5; i++)
            {
                number = myEvent.GetIndexNumber();
                Assert.IsFalse(numberList.Contains(number));
                numberList.Add(number);
            }
        }

        [Test, ExpectedException(typeof(EntitiesException), ExpectedMessage = "buzzword list must contain at least 25 words")]
        public void CreateBingoCardWithException()
        {
            IBingoEvent myEvent = new BingoEvent();
            IParticipant p = new Participant("email@dot.com");
            myEvent.CreateBingoCard(p);
        }

        [Test]
        public void CreateBingoCard()
        {
            IBingoEvent myEvent = new BingoEvent();

            for(int i=0; i<35; i++)
                myEvent.AddBuzzWord(new BuzzWord(i.ToString()));

            IParticipant p = new Participant("email@dot.com");
            myEvent.AddParticipant(p);
            myEvent.AddParticipant(new Participant("email1@dot.com"));
            myEvent.CreateBingoCard(p);
            string cardSTR = p.MyBingoCard.ToString();
        }

        [Test]
        public void MarkBuzzWord()
        {
            IBingoEvent myEvent = new BingoEvent();

            for (int i = 0; i < 35; i++)
                myEvent.AddBuzzWord(new BuzzWord(i.ToString()));

            IParticipant p1 = new Participant("email@dot.com");
            IParticipant p2 = new Participant("email1@dot.com");
            myEvent.AddParticipant(p1);
            myEvent.AddParticipant(p2);
            myEvent.CreateBingoCard(p1);
            myEvent.CreateBingoCard(p2);

            myEvent.Bingo += new EventHandler(myEvent_Bingo);
            _eventReceived = false;

            myEvent.MarkBuzzWord(p1, 0);
            myEvent.MarkBuzzWord(p1, 1);
            myEvent.MarkBuzzWord(p1, 2);
            myEvent.MarkBuzzWord(p1, 3);
            myEvent.MarkBuzzWord(p1, 4);
            Assert.IsTrue(_eventReceived);
        }

        void myEvent_Bingo(object sender, EventArgs e)
        {
            _eventReceived = true;
            _winner = ((IBingoEvent)sender).GetWinner();
        }

        [Test]
        public void GetBingoCard()
        {
            IBingoEvent myEvent = new BingoEvent();

            for (int i = 0; i < 35; i++)
                myEvent.AddBuzzWord(new BuzzWord(i.ToString()));

            IParticipant p = new Participant("email@dot.com");
            myEvent.AddParticipant(p);
            myEvent.AddParticipant(new Participant("email1@dot.com"));
            myEvent.CreateBingoCard(p);
            Assert.IsInstanceOf(typeof(BingoCard), myEvent.GetBingoCard(p));
        }

        [Test]
        public void GetWinner()
        {
            IBingoEvent myEvent = new BingoEvent();

            for (int i = 0; i < 35; i++)
                myEvent.AddBuzzWord(new BuzzWord(i.ToString()));

            IParticipant p1 = new Participant("email@dot.com");
            IParticipant p2 = new Participant("email1@dot.com");
            myEvent.AddParticipant(p1);
            myEvent.AddParticipant(p2);
            myEvent.CreateBingoCard(p1);
            myEvent.CreateBingoCard(p2);

            myEvent.Bingo += new EventHandler(myEvent_Bingo);
            _eventReceived = false;
            _winner = p2;

            myEvent.MarkBuzzWord(p1, 0);
            myEvent.MarkBuzzWord(p1, 1);
            myEvent.MarkBuzzWord(p1, 2);
            myEvent.MarkBuzzWord(p1, 3);
            myEvent.MarkBuzzWord(p1, 4);
            Assert.IsTrue(_eventReceived);
            Assert.AreSame(p1, _winner);
            Assert.AreNotSame(p2, _winner);
        }
    }
}
